package main

import(
/*
	"log"
	*/
	"math/rand"
	"strings"
	"questionnaire-gen/backend"
	"gopkg.in/mgo.v2/bson"
	"fmt"
	"net/http"
	"encoding/json"
	"errors"
)


func AdminCommands(w http.ResponseWriter, r *http.Request){
	adminCmd(w, r, ApplicationContext, nil)
}

func adminCmd(w http.ResponseWriter, r *http.Request, c *AppContext, rc *ReqContext) error{
	fmt.Println("Received admin cmd " )
	var cmd = &backend.JsonCommand{Org:new(backend.Org)}

	err := json.NewDecoder(r.Body).Decode(cmd)


	if err != nil{
		fmt.Printf("failed parsing command: %s\n" , err)
		http.Error(w, "Couldn't parse JsonCommand", http.StatusInternalServerError)
		return errors.New("Couldn't parse JsonCommand")
	}
	fmt.Println(cmd)

	var output interface{}

	switch cmd.Cmd{
	case "listOrgs": output, err = listOrgs(w, r, c , cmd)
	case "listUsers": output, err = listUsers(w, r, c , cmd)
	case "saveOrg": output, err = saveOrg(w, r, c , cmd)
	case "addOrgs": output, err = addOrgs(w, r, c , cmd)
	default:
		http.Error(w, "Command not found ", http.StatusInternalServerError)
		fmt.Fprintf(w, "command not found: %s", cmd.Cmd)
		return nil
	}

	if err != nil{
		http.Error(w, "Err executing command", http.StatusInternalServerError)
		fmt.Fprint(w, "Error executing command: " ,cmd.Cmd, " err:", err)
		return err
	}

	err = json.NewEncoder(w).Encode(output)
	return err
}

func findUsersWithInitials(start string) []*backend.User {
	list := make([]*backend.User, 0, 10)

	for k, v :=  range backend.Cache{
		if strings.HasPrefix(k, start ){
			v := v
			//item := &v
			list = append(list, v.(*backend.User))
		}
	}

	return list
}


func findUsers(suff string) []*backend.User {
	users := make([]*backend.User, 0)
	for k, v := range backend.Cache{
		if strings.HasSuffix(suff, k){
			v = v 
			user, ok := v.(*backend.User)
			if ok{
				users = append(users, user)
			}
		}

	}
	return users
}

func findOrgsWithInitials(start string) []*backend.Org {
	list := make([]*backend.Org, 0, 10)

	for k, v :=  range backend.Cache{
		if strings.HasPrefix(k, start ){
			v := v.(*backend.Org)
			//item := &v
			list = append(list, v)
		}
	}

	return list
}

func filter(prefix string, add func (item interface{}) ){
	for k, v :=  range backend.Cache{
		if strings.HasPrefix(k, prefix ){
			fmt.Println("adding to filter", k)
			add(v)
//			list = append(list, v)
		}
	}
}

func find(prefix string, f func(item interface{}) bool) interface{}{
	for k, v :=  range backend.Cache{
		if strings.HasPrefix(k, prefix ) && f(v){
			return v
		}
	}
	return nil
}


var letters = []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")

func randSeq(n int) string {
    b := make([]rune, n)
    for i := range b {
        b[i] = letters[rand.Intn(len(letters))]
    }
    return string(b)
}

func genId() string{
	return bson.NewObjectId().Hex()
}

func listOrgs(w http.ResponseWriter, r *http.Request, c *AppContext, cmd *backend.JsonCommand) (interface{}, error){
	_,result,  err := backend.Find(nil, backend.COrgs, nil, &[]backend.Org{}, false, true)
	return result, err

	//return findOrgsWithInitials("org_") , nil
}
func listUsers(w http.ResponseWriter, r *http.Request, c *AppContext,cmd *backend.JsonCommand) (interface{}, error){
	_, result, err := backend.Find(nil, backend.CUsers, nil, &[]backend.User{}, false, true)
	return result, err
	//return findUsersWithInitials("user_") , nil
}

func saveOrg(w http.ResponseWriter, r *http.Request, c *AppContext, cmd *backend.JsonCommand) (interface{}, error){
	//var org *backend.Org= rc.Payload["org"].(*backend.Org)
	//var org *backend.Org= cmd.Data["org"].(*backend.Org)
	org := cmd.Org

	s, o := backend.GetColl(nil, backend.COrgs)
	defer s.Close()

	if org.Id == ""{
		org.Id = bson.NewObjectId().Hex()
		err := o.Insert(org)
		return nil, err
	}

	err := o.Update(bson.M{"_id": org.Id}, org)
	fmt.Println("saveOrg: ", org)

	backend.Cache["org_"+org.Id] = org


	return nil, err
}
func addOrgs(w http.ResponseWriter, r *http.Request, c *AppContext,cmd *backend.JsonCommand) (interface{}, error){
	return nil, nil
}

